﻿using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using TimeTracker.Entities;
using TimeTracker.Persistence;

namespace TimeTracker.Web.Controllers
{
    public class InstallerController : Controller
    {
        private readonly dynamic defaultEntries = new[] 
        {
            new { Client = "Corvalius", Project = "Codealike", Description = "CodeCamp reference application", ElapsedTime = new TimeSpan(0,50,20), StartTime = DateTime.Now.Subtract(TimeSpan.FromDays(1)) },
            new { Client = "Corvalius", Project = "Codealike", Description = "CodeCamp reference application", ElapsedTime = new TimeSpan(3,00,12), StartTime = DateTime.Now.Subtract(TimeSpan.FromDays(2)) },
            new { Client = "Corvalius", Project = "Codealike", Description = MakeName(3), ElapsedTime = new TimeSpan(5,06,54), StartTime = DateTime.Now.Subtract(TimeSpan.FromDays(3)) },
            new { Client = "Corvalius", Project = "Codealike", Description = MakeName(3), ElapsedTime = new TimeSpan(1,30,20), StartTime = DateTime.Now.Subtract(TimeSpan.FromDays(8)) },
            new { Client = "Corvalius", Project = "Codealike", Description = MakeName(3), ElapsedTime = new TimeSpan(0,15,00), StartTime = DateTime.Now.Subtract(TimeSpan.FromDays(10)) },
            new { Client = "Corvalius", Project = "Codecamp", Description = "CodeCamp reference application", ElapsedTime = new TimeSpan(5,50,20), StartTime = DateTime.Now.Subtract(TimeSpan.FromDays(1)) },
            new { Client = "Corvalius", Project = "Codecamp", Description = "CodeCamp reference application", ElapsedTime = new TimeSpan(3,00,12), StartTime = DateTime.Now.Subtract(TimeSpan.FromDays(1)) },
            new { Client = "Corvalius", Project = "Codecamp", Description = "CodeCamp reference application", ElapsedTime = new TimeSpan(1,06,54), StartTime = DateTime.Now.Subtract(TimeSpan.FromDays(3)) },
            new { Client = "Corvalius", Project = "Codecamp", Description = MakeName(3), ElapsedTime = new TimeSpan(1,40,20), StartTime = DateTime.Now.Subtract(TimeSpan.FromDays(4)) },
            new { Client = "Corvalius", Project = "Codecamp", Description = MakeName(2), ElapsedTime = new TimeSpan(4,15,00), StartTime = DateTime.Now.Subtract(TimeSpan.FromDays(4)) },
            new { Client = "Microsoft", Project = "Codecamp Slides Masters", Description = MakeName(4), ElapsedTime = new TimeSpan(0,50,20), StartTime = DateTime.Now.Subtract(TimeSpan.FromDays(4)) },
            new { Client = "Microsoft", Project = "Codecamp Slides Masters", Description = MakeName(5), ElapsedTime = new TimeSpan(1,02,33), StartTime = DateTime.Now.Subtract(TimeSpan.FromDays(5)) },
            new { Client = "Microsoft", Project = "Codecamp Slides Masters", Description = MakeName(6), ElapsedTime = new TimeSpan(2,06,54), StartTime = DateTime.Now.Subtract(TimeSpan.FromDays(7)) },
            new { Client = "Microsoft", Project = "Codecamp Slides Masters", Description = MakeName(2), ElapsedTime = new TimeSpan(3,30,43), StartTime = DateTime.Now.Subtract(TimeSpan.FromDays(10)) },
            new { Client = "Microsoft", Project = "Codecamp Slides Masters", Description = MakeName(1), ElapsedTime = new TimeSpan(8,15,00), StartTime = DateTime.Now.Subtract(TimeSpan.FromDays(36)) },
        };

        private const string Alphabet = "abcdefghijklmnopqrstuvwyxzeeeiouea";
        private static readonly Random generator = new Random();

        public static char MakeLetter()
        {
            return Alphabet[generator.Next(Alphabet.Length)];
        }

        public static string MakeWord(int length)
        {
            return new string(
                Enumerable.Range(0, length + 1)
                    .Select(x => x == 0 ? char.ToUpper(MakeLetter()) : MakeLetter())
                    .ToArray());
        }

        public static string MakeName(int words = 2, string prefix = "", string suffix = "")
        {
            string result = string.Empty;
            if (!string.IsNullOrWhiteSpace(prefix))
                result += prefix + " ";

            for (int i = 0; i < words; i++)
            {
                result += MakeWord(generator.Next(5) + 3) + " ";
            }

            if (!string.IsNullOrWhiteSpace(suffix))
                result += suffix;
            else
                result = result.TrimEnd();

            return result;
        }

        public ActionResult Setup()
        {
            dynamic result = new ExpandoObject();
            try
            {                
                using (var context = new TimeTrackerBulkContext())
                {
                    var db = context.Database;

                    User user;
                    if (!db.TryGetUserByEmail("my-user@mailinator.com", out user))
                    {
                        user = new User {DisplayName = "Joe User", Email = "my-user@mailinator.com"};
                        db.Store(user);
                        db.SaveChanges();
                    }                    

                    // Creating dummy time
                    foreach (var item in db.Query<Entry>())
                        db.Delete(item);

                    db.SaveChanges();

                    foreach (var item in defaultEntries)
                    {
                        Client client;
                        if (!db.TryGetClientByName((string) item.Client, out client))
                        {
                            client = new Client {Name = (string) item.Client};
                            db.Store(client);
                        }

                        Project project;
                        if (!db.TryGetProjectByName((string) item.Project, out project))
                        {
                            project = new Project {Name = (string) item.Project};
                            db.Store(project);
                        }

                        var entry = new Entry
                                        {
                                            ClientId = client.Id,
                                            ProjectId = project.Id,
                                            UserId = user.Id,
                                            Description = item.Description,
                                            ElapsedTime = item.ElapsedTime,
                                            LastStartTime = item.StartTime
                                        };

                        db.Store(entry);
                        db.SaveChanges();
                    }                    
                }            

                result.Status = "successfully finished";
            }
            catch ( Exception e )
            {
                result.Status = "failed with error: " + e.Message;
            }

            return View(result);
        }

    }
}
